/****

    activequant - activestocks.eu

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License along
    with this program; if not, write to the Free Software Foundation, Inc.,
    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

	
	contact  : contact@activestocks.eu
    homepage : http://www.activestocks.eu

 ****/
package org.activequant.calendar;

import java.util.Map;
import java.util.TimeZone;

import org.activequant.core.types.Exchange;
import org.activequant.core.types.TimeStamp;
import org.activequant.math.algorithms.Interval;

/**
 * An interface to an exchange calendar. <br/>
 * An interface. Extends the ICalendar marker interface. Defines the following methods:
 * <ul>
 * <li>Exchange getExchange()</li>
 * <li>long getRegularOpeningTime()</li>
 * <li>long getRegularClosingTime()</li>
 * <li>IHolidayCalendar getHolidayCalendar()</li>
 * <li>TimeStamp getNextOpeningAsTimeStamp(final TimeStamp after)</li>
 * <li>TimeStamp getOpeningTimeTodayAsTimeStamp(final TimeStamp day)</li>
 * <li>TimeStamp getCloseTimeTodayAsTimeStamp(final TimeStamp day)</li>
 * <li>boolean isOpen(final TimeStamp when)</li>
 * <li>boolean isHoliday(final TimeStamp when)</li>
 * <li>TimeZone getTimeZone()</li>
 * <li>Map&lt;TimeStamp,Interval&lt;TimeStamp&gt;&gt; getTradingHours(final TimeStamp from, final TimeStamp to)</li>
 * </ul>
 * <b>History:</b><br>
 * - [May 30, 2008] Created (mark)<br>
 * - [Sep 5, 2008] added getTradingHours (mark)<br>
 * 
 * @author mark
 */
public interface IExchangeCalendar extends ICalendar {

	/**
	 * Get the exchange from the calendar.
	 * 
	 * @return the exchange for the calendar.
	 */
	Exchange getExchange();

	/**
	 * Get the regular opening time of the exchange. The regular opening time is the time the exchange would normally
	 * open when there are no 'special' events, like (partial-day) holidays etc.
	 * 
	 * @return the opening time in milliseconds after midnight in the exchange's time zone.
	 */
	long getRegularOpeningTime();

	/**
	 * Get the regular closing time of the exchange. The regular closing time is the time the exchange would normally
	 * close when there are no 'special' events, like (partial-day) holidays etc.
	 * 
	 * @return the closing time in milliseconds after midnight in the exchange's time zone.
	 */
	long getRegularClosingTime();

	/**
	 * Get the holiday calendar for the exchange.
	 * 
	 * @return the holiday calendar or null if no holiday calendar defined.
	 */
	IHolidayCalendar getHolidayCalendar();

	/**
	 * Get the next opening time of the exchange after a time stamp, taking into account holidays and business days.
	 * 
	 * @param after
	 *            the point in time after which to get the next opening for.
	 * @return the time stamp of the next opening of this exchange.
	 */
	TimeStamp getNextOpeningAsTimeStamp(final TimeStamp after);
	/**
	 * Get the last closing time of the exchange before a time stamp, taking into account holidays and business days.
	 * 
	 * @param before
	 *            the point in time before which to get the last closing for.
	 * @return the time stamp of the last closing of this exchange.
	 */
	TimeStamp getLastClosingAsTimeStamp(final TimeStamp before);
	/**
	 * Get the time the exchange opened (or will open) for a specified <code>day</code>, taking into account holidays
	 * and business days.
	 * 
	 * @param day
	 *            the time stamp with the day for which to get the opening time stamp for.
	 * @return the time stamp of the opening of this exchange, or <code>null</code> if the exchange will not be open.
	 */
	TimeStamp getOpeningTimeTodayAsTimeStamp(final TimeStamp day);

	/**
	 * Get the time the exchange closed (or will close) for a specified <code>day</code>, taking into account holidays
	 * and business days.
	 * 
	 * @param day
	 *            the time stamp with the day for which to get the close time stamp for.
	 * @return the time stamp of the close of this exchange, or <code>null</code> if the exchange is not opened.
	 */
	TimeStamp getCloseTimeTodayAsTimeStamp(final TimeStamp day);

	/**
	 * Determine if the exchange is open, taking into account holidays and business days and the time part.
	 * 
	 * @param when
	 *            the point in time for which to check if the exchange is open
	 * @return true if the exchange is open, otherwise false.
	 */
	boolean isOpen(final TimeStamp when);

	/**
	 * Look up if the given time stamp is a holiday for the exchange
	 * 
	 * @param when
	 *            the time stamp to look up in this calendar
	 * @return true if the given time stamp is on a holiday, otherwise false
	 */
	boolean isHoliday(final TimeStamp when);

	/**
	 * Get the time zone for the exchange calendar.
	 * 
	 * @return the time zone for the exchange calendar.
	 */
	TimeZone getTimeZone();

	/**
	 * Get a <code>Map</code> with opening and closing times of the exchange for a specific time period, taking into
	 * account holidays and business days. The key of each entry of the map will be a <code>TimeStamp</code> for the day
	 * with the time part truncated to midnight. Only the days for which the exchange is at least partially opened will
	 * be returned as a entry in the map.
	 * 
	 * @param from
	 *            the first day to get the opening time for (inclusive)
	 * @param to
	 *            the last day to get the opening time for (exclusive)
	 * 
	 * @return map with <code>Interval</code> entries with opening and closing time for the trading days from
	 *         <code>from</code> to <code>to</code>.
	 */
	Map<TimeStamp, Interval<TimeStamp>> getTradingHours(final TimeStamp from, final TimeStamp to);
}
